package com.yuyue.springFramework.note14.aspect;

import com.yuyue.springFramework.note14.entity.Animal;
import com.yuyue.springFramework.note14.entity.Lion;
import com.yuyue.springFramework.note14.entity.Person;
import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 声明切面
 */
//Xml风格时注释
@Aspect
//切面声明并不具备被类路径扫描功能，因此需要加上@Component
@Component
public class MyAspect {
    //声明切入点
    @Pointcut("execution(* com.yuyue.springFramework.note14.dao.*Dao.*(..))")//切入点表达式
    public void dao(){//切入点签名
        System.out.println("Dao的切入点方法");
    }

    //前增强，指定切入点
    @Before("com.yuyue.springFramework.note14.aspect.MyAspect.dao()")
    public void beforeDao(){
        System.out.println("before1");
    }

    //前增强，直接指定切入点表达式
    @Before("execution(* com.yuyue.springFramework.note14.dao.*Dao.*(..))")
    public void beforeDaoNoFun(){
        System.out.println("before2");
    }

    //前增强中获取切入点信息
    @Before("com.yuyue.springFramework.note14.aspect.MyAspect.dao()")
    public void beforeAddProcess(JoinPoint joinPoint){
        //从joinPoint获取信息
        System.out.println("before3 " + joinPoint.getSignature());
    }

    //获取参数
    @Before(value = "com.yuyue.springFramework.note14.aspect.MyAspect.dao() && args(person,..)")
    public void beforeAddParam(Person person){
        System.out.println("before4" + person);
    }

    //切入点
    @Pointcut("execution(* com.yuyue.springFramework.note14.dao.*Dao.*(..))")
    public void update(){ }

    //成功返回增强,无返回参数增强
    @AfterReturning("com.yuyue.springFramework.note14.aspect.MyAspect.update()")
    private void updateTable2(){
        System.out.println("无参数AfterReturning 增强");
    }

    //带返回参数增强，参数名称需要增强方法名称保持一致
    @AfterReturning(pointcut = "com.yuyue.springFramework.note14.aspect.MyAspect.update()", returning = "retValue")
    public void updateTable(Integer retValue){
        System.out.println("AfterReturning 增强" + retValue);
    }

    //异常返回后增强
    @AfterThrowing("com.yuyue.springFramework.note14.aspect.MyAspect.update()")
    public void throwsProcess(){
        System.out.println("异常处理1");
    }

    //指定异常类型的异常返回后增强
    @AfterThrowing(pointcut = "com.yuyue.springFramework.note14.aspect.MyAspect.update()", throwing = "e")
    public void exceptionProcess(ArithmeticException e){
    //public void exceptionProcess(NullPointerException e){
        System.out.println("异常处理2:" + e.getMessage());
    }

    //最终返回增强
    @After("com.yuyue.springFramework.note14.aspect.MyAspect.update()")
    public void afterFinally(){
        System.out.println("关闭连接");
    }

    //环绕增强
    @Around("com.yuyue.springFramework.note14.aspect.MyAspect.update()")
    public void aroundFun(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
        //环绕前处理
        System.out.println("环绕前处理1");

        //被通知方法执行
        Object obj = proceedingJoinPoint.proceed();

        //环绕后处理
        System.out.println("环绕后处理2" + obj);
    }

    //为Human接口的实现类附加Animal接口的（默认Lion类）实现方法
    @DeclareParents(value = "com.yuyue.springFramework.note14.entity.Human+", defaultImpl = Lion.class)
    public Animal animal;
}
